﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ledict.ConditionExtract.Common;
using Lucene.Net.Analysis.CJK;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;

namespace Ledict.ConditionExtract.BLL
{
    public class LuceneSearch
    {
        private IndexSearcher search;

        public LuceneSearch()
        {
            //string result = Convert.ToString(WNetConnectionHelper.WNetAddConnection("administrator", "ldtlaw_123", @"192.168.1.160//xurenna", null));
            string indexPath = ConfigurationManager.AppSettings["luceneRoot"];
            LdIndexReader ldReader = LdIndexReader.GetInstance();
            IndexReader indexReader = ldReader.GetIndexReader(indexPath); //把刚才建立的索引取出来
            search = new IndexSearcher(indexReader);
            //uint n = WNetConnectionHelper.WNetCancelConnection("//192.168.1.160//xurenna", 1, true);//关闭160链接
        }


        public DataTable GetDataSource(DataSourceCondition conditon, int pag, int perPage)
        {
            BooleanQuery query = new BooleanQuery();

            AddFuzzyQuery("AllParentID", conditon.HeadwordId, Occur.MUST, query);
            AddTermQuery("JudicialProcedureId", conditon.JudicialProcedureId, Occur.MUST, query);
            AddTermQuery("PropertyId", conditon.PropertyId, Occur.MUST, query);
            AddTermQuery("ParagraphTypeId", conditon.ParagraphType, Occur.MUST, query);
            if (conditon.CaseIdStart != "" && conditon.CaseIdEnd != "")
                AddTermRangeQuery("CaseId", conditon.CaseIdStart, conditon.CaseIdEnd, Occur.MUST, query);
            AddTermQuery("ParagraphTypeId", conditon.ParagraphType, Occur.MUST, query);
            //  AddQueryParser("Sentence", "争议焦点", Occur.MUST, query);

            //排序
            Sort fieldSort = new Sort(new SortField("SentenceTime", SortField.STRING, true));

            TopDocs topdocs = search.Search(query, null, pag * perPage, fieldSort);
            ScoreDoc[] scoreDocs = topdocs.ScoreDocs; // 搜索返回的结果集合

            //查询起始记录位置
            int begin = perPage * (pag - 1);

            //查询终止记录位置
            int end = Math.Min(begin + perPage, scoreDocs.Length);
            DataTable dt = new DataTable();
            dt.Columns.Add("Id");
            dt.Columns.Add("CaseId");
            dt.Columns.Add("ParagraphTypeId");
            dt.Columns.Add("ParagraphText");

            for (int i = begin; i < end; i++)
            {
                Document doc = search.Doc(scoreDocs[i].Doc);
                DataRow dr = dt.NewRow();
                dr[0] = doc.Get("SentenceId");
                dr[1] = doc.Get("CaseId");
                dr[2] = doc.Get("ParagraphTypeId");
                dr[3] = doc.Get("Sentence");
                dt.Rows.Add(dr);
            }

            return dt;

        }
        public int GetDataSourceCount(DataSourceCondition conditon)
        {
            BooleanQuery query = new BooleanQuery();
            AddFuzzyQuery("AllParentID", conditon.HeadwordId, Occur.MUST, query);
            AddTermQuery("JudicialProcedureId", conditon.JudicialProcedureId, Occur.MUST, query);
            AddTermQuery("PropertyId", conditon.PropertyId, Occur.MUST, query);
            AddTermQuery("ParagraphTypeId", conditon.ParagraphType, Occur.MUST, query);
            if (conditon.CaseIdStart != "" && conditon.CaseIdEnd != "")
                AddTermRangeQuery("CaseId", conditon.CaseIdStart, conditon.CaseIdEnd, Occur.MUST, query);
            TopDocs topdocs = search.Search(query, 1);
            int totalCount = topdocs.TotalHits;
            return totalCount;
        }


        #region  各种lucene查询方法
        /// <summary>
        /// 普通查询
        /// </summary>
        /// <param name="whereName"></param>
        /// <param name="whereValue"></param>
        /// <param name="occur"></param>
        /// <param name="query"></param>
        private void AddTermQuery(string whereName, string whereValue, Lucene.Net.Search.Occur occur, BooleanQuery query)
        {

            whereValue = whereValue.Trim();
            if (!String.IsNullOrEmpty(whereValue) || occur == Occur.MUST_NOT)
            {
                Term term = new Term(whereName, whereValue);
                Query termquery = new TermQuery(term);
                query.Add(termquery, occur);
            }
        }
        /// <summary>
        /// 分词模糊查询
        /// </summary>
        /// <param name="whereName"></param>
        /// <param name="whereValue"></param>
        /// <param name="occur"></param>
        /// <param name="query"></param>
        private void AddQueryParser(string whereName, string whereValue, Lucene.Net.Search.Occur occur, BooleanQuery query)
        {

            whereValue = new System.Text.RegularExpressions.Regex("[\\s]+").Replace(whereValue, " ");
            if (!String.IsNullOrEmpty(whereValue))
            {
                BooleanQuery queryChild = new BooleanQuery();
                string[] queryArr = whereValue.Split(new char[] { ',', ' ', '，' });
                foreach (string str in queryArr)
                {
                    if (!String.IsNullOrEmpty(str))
                    {

                        if (str.Length == 1)
                        {
                            Term termwildcard = new Term(whereName, "*" + str + "*");//模糊查询有问题
                            Query wildcardquery = new WildcardQuery(termwildcard);
                            queryChild.Add(wildcardquery, Occur.MUST);
                        }
                        else
                        {   //非法字符
                            CJKAnalyzer analyzer = new CJKAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
                            QueryParser WhereNameparser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, whereName, analyzer);
                            Query WhereNamequery = WhereNameparser.Parse(str);
                            queryChild.Add(WhereNamequery, Occur.MUST);
                        }
                    }
                }
                query.Add(queryChild, occur);
            }
        }


        /// <summary>
        /// 时间查询
        /// </summary>
        /// <param name="whereName"></param>
        /// <param name="whereValue1"></param>
        /// <param name="whereValue2"></param>
        /// <param name="occur"></param>
        /// <param name="query"></param>
        private void AddTermRangeQuery(string whereName, string whereValue1, string whereValue2, Lucene.Net.Search.Occur occur, BooleanQuery query)
        {
            if (!String.IsNullOrEmpty(whereValue1))
            {
                TermRangeQuery Timequery = new TermRangeQuery(whereName, whereValue1, whereValue2, true, true);
                query.Add(Timequery, occur);

            }
        }
        /// <summary>
        /// 通配符查询
        /// </summary>
        /// <param name="whereName"></param>
        /// <param name="whereValue"></param>
        /// <param name="occur"></param>
        /// <param name="query"></param>
        private void AddWildcardQuery(string whereName, string whereValue, Lucene.Net.Search.Occur occur, BooleanQuery query)
        {
            whereValue = whereValue.Trim();
            if (!String.IsNullOrEmpty(whereValue))
            {
                Term termwildcard = new Term(whereName, "*" + whereValue + "*");
                Query wildcardquery = new WildcardQuery(termwildcard);
                query.Add(wildcardquery, occur);

            }
        }

        /// <summary>
        /// 前缀匹配
        /// </summary>
        /// <param name="whereName"></param>
        /// <param name="whereValue"></param>
        /// <param name="occur"></param>
        /// <param name="query"></param>
        private void AddFuzzyQuery(string whereName, string whereValue, Lucene.Net.Search.Occur occur, BooleanQuery query)
        {
            if (!String.IsNullOrEmpty(whereValue))
            {
                Term termwildcard = new Term(whereName, whereValue + "*");
                Query wildcardquery = new WildcardQuery(termwildcard);
                query.Add(wildcardquery, occur);

            }
        }

        #endregion
    }
}
